package cn.wind.xboot.module.web.handler;

import cn.hutool.core.util.ReUtil;
import cn.hutool.http.HttpUtil;
import cn.wind.xboot.core.utils.IpInfoUtil;
import cn.wind.xboot.core.utils.SpringUtil;
import cn.wind.xboot.core.utils.ThreadPoolUtil;
import cn.wind.xboot.core.utils.UserUtil;
import cn.wind.xboot.logic.sys.entity.SysLog;
import cn.wind.xboot.logic.sys.service.ISysLogService;
import cn.wind.xboot.logic.sys.service.impl.SysLogServiceImpl;
import cn.wind.klog.annotation.Log;
import cn.wind.klog.annotation.LogFilterType;
import cn.wind.klog.handlers.LogHandler;
import cn.wind.klog.handlers.LogHandlerHelp;
import cn.wind.xboot.framework.constant.ActionConstant;
import cn.wind.xboot.framework.constant.ModuleConstant;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

/**
 * <p>Title: MyLogAroundHandler</p>
 * <p>Description: TODO</p>
 *
 * @author xukk
 * @version 1.0
 * @date 2018/6/29
 */
public class MyLogHandler implements LogHandler<Log,Object>{

    private static final ThreadLocal<Date> beginTimeThreadLocal = new NamedThreadLocal<Date>("ThreadLocal beginTime");

    @Override
    public Object handlerBefore(Log log, JoinPoint joinPoint) {
        //线程绑定变量（该数据只有当前请求的线程可见）
        Date beginTime=new Date();
        beginTimeThreadLocal.set(beginTime);
        return null;
    }

    @Override
    public Object handlerAfter(Log log, JoinPoint joinPoint,Object o) {
        HttpServletRequest request= ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String currentUser= UserUtil.principal();
        //请求开始时间
        long beginTime = beginTimeThreadLocal.get().getTime();
        String value=log.filterType().equals(LogFilterType.String)?log.value(): LogHandlerHelp.executeTemplate(log.pattern(),joinPoint);
        SysLog sysLog=new SysLog();
        //日志标题
        sysLog.setName(value);
        //日志请求url
        sysLog.setRequestUrl(request.getRequestURI());
        //请求方式
        sysLog.setRequestType(request.getMethod());
        //请求参数
        Map<String,String[]> logParams=request.getParameterMap();
        sysLog.setMapToParams(logParams);
        //请求用户
        sysLog.setUsername(currentUser!=null? ReUtil.getGroup0("(?<=\\.*)\\d+",currentUser):"");
        //请求IP
        sysLog.setIp(HttpUtil.getClientIP(request));
        if(StringUtils.equalsIgnoreCase(log.module(), ModuleConstant.USER)&&StringUtils.equalsIgnoreCase(log.action(), ActionConstant.LOGIN)){
            //IP地址
            sysLog.setIpInfo(IpInfoUtil.getIpCity(HttpUtil.getClientIP(request)));
        }
        sysLog.setDeleteFlag(0);
        //IP地址
        sysLog.setCreateBy(currentUser);
        sysLog.setUpdateBy(sysLog.getCreateBy());
        sysLog.setCreateTime(new Date());
        sysLog.setUpdateTime(sysLog.getCreateTime());
        sysLog.setModule(log.module());
        sysLog.setAction(log.action());
        sysLog.setChannel(log.channel());
        long endTime = System.currentTimeMillis();
        //请求耗时
        Long logElapsedTime = endTime - beginTime;
        sysLog.setCostTime(logElapsedTime.intValue());
        ThreadPoolUtil.getPool().execute(()->{
            ISysLogService sysLogService=SpringUtil.getBean(SysLogServiceImpl.class);
            sysLogService.save(sysLog);

        });
        return null;
    }
}
